#include "stdafx.h"
#include <math.h>
#include "ValidatorContext.h"
#include "CombatSessionImp.h"

void TContextValidators::OnArchieveReaded()
{
	m_vValidators.clear();
	if(m_iID==INVALID_ID) return ;
	do{
	
		if(m_iTurnNum==INVALID_ID) break;
		if(m_eTurnNumCamp==eCompare_Null) break;
		VContext_TurnNum* pValidator=new VContext_TurnNum();
		pValidator->InitData(m_iTurnNum,m_eTurnNumCamp);
		Add(TContextValidatorPtr(pValidator));
	}while(0);
	
	TContextValidatorPtr pVCardNum1;
	do{
		if(m_tiBeOurSide==eTriple_Null) break;
		if(m_eFieldType==INVALID_ID) break;
		if(m_vTypes.empty()&&m_vRaces.empty()) break;
		if(m_iCardNum==INVALID_ID) break;
		if(m_eCardNumComp==eCompare_Null) break;

		VContext_FieldCardNum* pValidator=new VContext_FieldCardNum();
		pValidator->InitData(m_tiBeOurSide==eTriple_True,m_eFieldType,m_vRaces,m_vTypes,m_iCardNum,m_eCardNumComp);
		pVCardNum1=TContextValidatorPtr(pValidator);

	}while(0);

	TContextValidatorPtr pVCardNum2;
	do{
		if(m_tiBeOurSide2==eTriple_Null) break;
		if(m_eFieldType2==INVALID_ID) break;
		if(m_vTypes2.empty()&&m_vRaces2.empty()) break;
		if(m_iCardNum2==INVALID_ID) break;
		if(m_eCardNumComp2==eCompare_Null) break;

		VContext_FieldCardNum* pValidator=new VContext_FieldCardNum();
		pValidator->InitData(m_tiBeOurSide2==eTriple_True,m_eFieldType2,m_vRaces2,m_vTypes2,m_iCardNum2,m_eCardNumComp2);
		pVCardNum2=TContextValidatorPtr(pValidator);

	}while(0);


	if(m_eLogicPot!=ELogicOpt_NULL)
	{
		VContext_Compose* pValidator=new VContext_Compose();
		pValidator->InitData(m_eLogicPot,pVCardNum1,pVCardNum2);
		Add(TContextValidatorPtr(pValidator));
	}
	


	do{
		if(m_tiBeOurSideHeroHp==eTriple_Null) break;
		VContext_HeroHp* pValidator=new VContext_HeroHp();
		pValidator->InitData(m_tiBeOurSideHeroHp!=0,m_fHeroHpPercent,m_eHeroHpComp);
		Add(TContextValidatorPtr(pValidator));

	}while(0);

	do{
		if(m_tiBeOurSideTombLock==eTriple_Null) break;
		VContext_TombLock* pValidator=new VContext_TombLock();
		pValidator->InitData(m_tiBeOurSideTombLock==eTriple_True,m_bLock);
		Add(TContextValidatorPtr(pValidator));

	}while(0);
}

bool VContext_TurnNum::Validate( uint8 iPlayerID,CombatSessionImp * pContext )const 
{
	switch(m_eCompare)
	{
	case eCompare_Equal:
		   {
			   return  pContext->GetRoundNum()==m_iTurnNum;
			
		   }
	case eCompare_Greater:
		{
			return  pContext->GetRoundNum()>m_iTurnNum;

		}
	case eCompare_Less:
		{
			return pContext->GetRoundNum()<m_iTurnNum;
		}
		default:
			return false;
	}
}

bool VContext_FieldCardNum::Validate( uint8 iPlayerID,CombatSessionImp * pContext )const 
{
	uint8 iCompID=m_bOurSide?iPlayerID:(iPlayerID+1)%2;
	uint8 iCount=0;
	switch(m_eFieldType)
	{
	case ECardStorage_BattleField:
		{
			if(m_vCardRaces.size()>0) iCount =pContext->GetBattleField(iCompID).CoutCardOfRaces(m_vCardRaces);
			if(m_vCardTypes.size()>0) iCount =pContext->GetBattleField(iCompID).CoutCardOfTypes(m_vCardTypes);
		}break;
	case ECardStorage_InHeap:
		{
			if(m_vCardRaces.size()>0) iCount =pContext->GetHeapField(iCompID).CoutCardOfRaces(m_vCardRaces);
			if(m_vCardTypes.size()>0) iCount =pContext->GetHeapField(iCompID).CoutCardOfTypes(m_vCardTypes);
		}break;
		
	case ECardStorage_InHand:		
		{
			if(m_vCardRaces.size()>0) iCount =pContext->GetHandField(iCompID).CoutCardOfRaces(m_vCardRaces);
			if(m_vCardTypes.size()>0) iCount =pContext->GetHandField(iCompID).CoutCardOfTypes(m_vCardTypes);
		}break;
	case ECardStorage_InTomb:
		{
			if(m_vCardRaces.size()>0) iCount =pContext->GetTombField(iCompID).CoutCardOfRaces(m_vCardRaces);
			if(m_vCardTypes.size()>0) iCount =pContext->GetTombField(iCompID).CoutCardOfTypes(m_vCardTypes);
		}break;
	default:
		return false;

	}
	
	switch(m_eCompare)
	{
	case eCompare_Equal:
		{
			return iCount==m_iCompNum;

		}
	case eCompare_Greater:
		{
			return  iCount>m_iCompNum;

		}
	case eCompare_Less:
		{
			return iCount<m_iCompNum;
		}
	default:
		return false;
	}

}

bool VContext_HeroHp::Validate( uint8 iPlayerID,CombatSessionImp * pContext ) const 
{
	uint8 iCompID=m_bOurSide?iPlayerID:(iPlayerID+1)%2;
	double fPercent= pContext->GetHero(iCompID).GetHp()/(pContext->GetHero(iCompID).GetHpMax()*1.f);

	switch(m_eCompare)
	{
	case eCompare_Equal:
		{
			return fabs(fPercent - m_fHeroHpPercent) < 1e-6;

		}
	case eCompare_Greater:
		{
			return  fPercent>m_fHeroHpPercent;

		}
	case eCompare_Less:
		{
			return fPercent<m_fHeroHpPercent;
		}
	default:
		return false;
	}

}

bool VContext_Compose::Validate( uint8 iPlayerID,CombatSessionImp * pContext ) const
{
	switch(m_eLogicOpt)
	{
	case ELogicOpt_NULL :
		{
			return true;
		}
	case ELogicOpt_And:
		{
			if(!m_pV1)
				return false;
			if(!m_pV2)
				return false;
			return m_pV1->Validate(iPlayerID,pContext) &&m_pV2->Validate(iPlayerID,pContext);
		}break;
	case ELogicOpt_Or:
		{
			if(m_pV1 && m_pV1->Validate(iPlayerID,pContext)) return true;
			if(m_pV2 && m_pV2->Validate(iPlayerID,pContext)) return true;
			return false;
		}
	default:
		return false;
	}
}

bool VContext_HeroSP::Validate( uint8 iPlayerID,CombatSessionImp * pContext ) const
{
	uint8 iCompID=m_bOurSide?iPlayerID:(iPlayerID+1)%2;
	double iValue= pContext->GetHero(iCompID).GetRage();

	switch(m_eCompare)
	{
	case eCompare_Equal:
		{
			return  fabs( iValue - m_iSpValue) < 1e-6;

		}
	case eCompare_Greater:
		{
			return  iValue>m_iSpValue;

		}
	case eCompare_Less:
		{
			return iValue<m_iSpValue;
		}
	default:
		return false;
	}
}

bool VContext_TombLock::Validate( uint8 iPlayerID,CombatSessionImp * pContext ) const
{
	uint8 iCompID=m_bOurSide?iPlayerID:(iPlayerID+1)%2;
	if(m_bLock)
	{
		return pContext->GetTombLock(iCompID)>0;
	}
	else
	{
		return pContext->GetTombLock(iCompID)<=0;
	}
}